using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics;
using System.IO;
using System.Text.RegularExpressions;
using System.Drawing;

namespace VideoCutter.Helper
{
    class VideoHelper
    {
        static readonly string SNAPSHOT_FILE_NAME = "snapshot.jpg";
        public static string GetVideoDurationStr(string path)
        {
            Process process = new Process()
            {
                StartInfo = new ProcessStartInfo()
                {
                    FileName = AppHelper.GetResourcePath(@"res\ffmpeg.exe"),
                    Arguments = " -i \"" + path + "\"",
                    UseShellExecute = false,
                    RedirectStandardInput = true,
                    RedirectStandardOutput = true,
                    RedirectStandardError = true,
                    CreateNoWindow = true,
                }
            };
            LogHelper.WriteLog(LogType.ffmpeg_command, process.StartInfo.Arguments);
            process.Start();
            process.WaitForExit();
            string errOutput = process.StandardError.ReadToEnd();
            string output = process.StandardOutput.ReadToEnd();
            LogHelper.WriteLog(LogType.ffmpeg_info, output);
            LogHelper.WriteLog(LogType.ffmpeg_error, errOutput);
            process.Close();
            Regex r = new Regex(@"Duration\:\s+(\d+\:\d+\:\d+\.\d+)");
            var searchResult = r.Match(errOutput);
            if (searchResult.Success)
            {
                return searchResult.Groups[1].Value;
            }
            else
            {
                return "00:00:00.00";
            }
        }
        public static Image GetVideoSnapshot(string path, TimeSpan time)
        {
            TimeSpan timeBefore = time - new TimeSpan(0, 0, 10);
            TimeSpan startSearchTime = new TimeSpan(0, 0, 10);
            if (timeBefore < AppVars.emptyTimeSpan)
            {
                timeBefore = AppVars.emptyTimeSpan;
                startSearchTime = time;
            }
            Process process = new Process()
            {
                StartInfo = new ProcessStartInfo()
                {
                    //快速搜索到21s,然后精确查找31s
                    //ffmpeg -ss 00:00:21 -i sample1.mp4 -ss 00:00:10 -f image2 -vframes 1 -y test1.jpg
                    FileName = AppHelper.GetResourcePath(@"res\ffmpeg.exe"),
                    Arguments = String.Format(" -ss {0} -i \"{1}\" -ss {3} -f image2 -vframes 1 -y {2}",
                    Helper.StringHelper.TimeSpan2Str(timeBefore),
                    path,
                    SNAPSHOT_FILE_NAME,
                    Helper.StringHelper.TimeSpan2Str(startSearchTime)),
                    UseShellExecute = false,
                    RedirectStandardInput = true,
                    RedirectStandardOutput = true,
                    RedirectStandardError = true,
                    CreateNoWindow = true,
                }
            };
            LogHelper.WriteLog(LogType.ffmpeg_command, process.StartInfo.Arguments);
            process.Start();
            process.WaitForExit();
            string errOutput = process.StandardError.ReadToEnd();
            string output = process.StandardOutput.ReadToEnd();
            LogHelper.WriteLog(LogType.ffmpeg_info, output);
            LogHelper.WriteLog(LogType.ffmpeg_error, errOutput);
            process.Close();
            int retryCount = -2000;
            string imageFileName = AppHelper.GetResourcePath(SNAPSHOT_FILE_NAME);
            while (!File.Exists(imageFileName))
            {
                if (retryCount >= 0)
                {
                    return null;
                }
                retryCount++;
                System.Threading.Thread.Sleep(1);
            }
            Image img = null;
            using (FileStream fs = new FileStream(imageFileName, FileMode.Open, FileAccess.Read))
            {
                img = Image.FromStream(fs);
                fs.Close();
            }
            File.Delete(imageFileName);
            return img;
        }

        public static string generateCutVideoCmd(string path, TimeSpan start, TimeSpan end)
        {
            String newPath = Path.Combine(Path.GetDirectoryName(path), "[NoAd]" + Path.GetFileNameWithoutExtension(path) + Path.GetExtension(path));

            String cmd = "ffmpeg.exe" + String.Format(" -ss {0} -i \"{2}\" -to {1} -c copy -y \"{3}\"",
                        start.ToString("hh\\:mm\\:ss\\.fff"),
                        (end - start).ToString("hh\\:mm\\:ss\\.fff"),
                        path,
                        newPath);
            return cmd;
        }

        public static void CutVideo(string path, TimeSpan start, TimeSpan end)
        {
            String newPath = Path.Combine(Path.GetDirectoryName(path), "c_" + Path.GetFileNameWithoutExtension(path) + Path.GetExtension(path));
            Process process = new Process()
            {
                StartInfo = new ProcessStartInfo()
                {
                    //不用  -ss 00:00:33.900 - to 00:27:49.400 -accurate_seek -i "sample3.mp4" - vcodec copy - acodec copy - copyts - y - avoid_negative_ts 1 "sample3_cut.mp4"
                    // -i "sample3.mp4" -ss 00:00:33.500 -to 00:27:49.400  -c copy -y "sample3_cut.mp4"
                    FileName = AppHelper.GetResourcePath(@"res\ffmpeg.exe"),
                    Arguments = String.Format(" -i \"{2}\" -ss {0} -to {1} -c copy -y \"{3}\"",
                        start.ToString("hh\\:mm\\:ss\\.fff"),
                        end.ToString("hh\\:mm\\:ss\\.fff"),
                        path,
                        newPath),
                    UseShellExecute = false,
                    RedirectStandardInput = true,
                    RedirectStandardOutput = true,
                    RedirectStandardError = true,
                    CreateNoWindow = true,
                }
            };
            LogHelper.WriteLog(LogType.ffmpeg_command, process.StartInfo.Arguments);
            try
            {
                process.Start();
                string errOutput = process.StandardError.ReadToEnd();
                string output = process.StandardOutput.ReadToEnd();
                LogHelper.WriteLog(LogType.ffmpeg_info, output);
                LogHelper.WriteLog(LogType.ffmpeg_error, errOutput);
                process.WaitForExit();
                process.Close();
            }
            catch (Exception ex)
            {
                LogHelper.WriteLog(LogType.general_error, ex.Message);
            }
        }
    }
}
